package model;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;

public class Termin extends ModelID {
	
	private String thema;
	private String beschreibung;
	private Date terminAnfang;
	private Date terminEnde;
	private TerminArt terminArt;
	private Integer prioritaet; // 1-5, 5 ist hoch
	private Adresse adresse;
	private Set<Teilnehmer> teilnehmerliste; 
	private List<Anlage> anlagen;
	static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm");
	
	
	public static enum TerminArt{GESCHAEFTLICH("Geschaeftlich"),PRIVAT("Privat"),URLAUB("Urlaub"),SONSTIGES("Sonstiges"),GEBURTSTAG("Geburtstag");
	 		private String key;
	 		
	 		private TerminArt(String key)
	 		{this.key = key;}
	 		
	 		public String getKey()
	 		{return key;}
	 		
	 		public static TerminArt getTerminArt(String key){
	 		for(TerminArt TA :TerminArt.values())
	 			if(TA.getKey().equalsIgnoreCase(key))
	 				return TA;
			throw new IllegalArgumentException("Key nicht gefunden!");
	 		}
	}



	public Termin(String thema, String beschreibung, Date terminAnfang,
			Date terminEnde, TerminArt terminArt, Integer prioritaet,
			Adresse adresse) 
	{
		setThema(thema);
		setBeschreibung(beschreibung);
	    setTerminAnfang(terminAnfang);
		setTerminEnde(terminEnde);
		setPrioritaet(prioritaet);
		setTerminArt(terminArt);
		setAdresse(adresse);
		teilnehmerliste = new TreeSet<Teilnehmer>();
		anlagen = new ArrayList<Anlage>();
		
	}
	
	

	public String getThema() {
		return thema;
	}

	public String getBeschreibung() {
		return beschreibung;
	}

	public Adresse getAdresse() {
		return adresse;
	}

	public Date getTerminAnfang() {
		return (Date) terminAnfang.clone();
	}

	 public String getFormattedTerminAnfang() {
	    return sdf.format(terminAnfang);
	  }
	
	public Date getTerminEnde() {
		return (Date) terminEnde.clone();
	}

  public String getFormattedTerminEnde() {
    return sdf.format(terminEnde);
  }

	public TerminArt getTerminArt() {
		return terminArt;
	}


	public Set<Teilnehmer> getTeilnehmer() {
		return Collections.unmodifiableSet(teilnehmerliste);
	}

	public List<Anlage> getAnlagen() {
		return Collections.unmodifiableList(anlagen);
	}


	public Integer getPrioritaet() {
		return prioritaet;
	}


	public void setThema(String thema) {
		if(thema == null || thema.trim().length() == 0) throw new IllegalArgumentException("Thema darf nicht null sein!");
		this.thema = thema;
	}


	public void setBeschreibung(String beschreibung) {
		if(beschreibung == null || beschreibung.trim().length() == 0) throw new IllegalArgumentException("Beschreibung darf nicht null sein!");
		this.beschreibung = beschreibung;
	}


	public void setAdresse(Adresse adresse) {
		if(adresse == null) throw new IllegalArgumentException("Adresse darf nicht null sein!");
		{if(this.adresse != null)
			this.adresse.removeTermin();
		this.adresse = adresse;
		adresse.setTermin(this);
		}
	}


	public void setTerminAnfang(Date terminAnfang) {
		if(terminAnfang == null) throw new IllegalArgumentException("TerminAnfang darf nicht null sein!");
		if(terminEnde != null)
		if(terminAnfang.after(terminEnde)) throw new IllegalArgumentException("TerminAnfang darf nicht NACH TerminEnde sein!");
		this.terminAnfang = (Date) terminAnfang.clone();
	}


	public void setTerminEnde(Date terminEnde) {
		if(terminEnde == null) throw new IllegalArgumentException("TerminEnde darf nicht null sein!");
	  if(terminAnfang != null)
	    if(terminEnde.before(terminAnfang)) throw new IllegalArgumentException("TerminEnde darf nicht VOR TerminAnfang sein!");
	      
		this.terminEnde = (Date) terminEnde.clone();
	}


	public void setTerminArt(TerminArt terminArt) {
		if(terminArt == null) throw new IllegalArgumentException("TerminArt darf nicht null sein!");
		this.terminArt = terminArt;
	}




	public void setPrioritaet(Integer prioritaet) {
		if(prioritaet == null )
			throw new IllegalArgumentException("Prioritaet darf nicht null sein!");
		
		if(prioritaet.intValue() >= 1 && prioritaet.intValue() <= 5)
		    	this.prioritaet = prioritaet;
		else
			throw new IllegalArgumentException("Prioritaet muss zwischen 1 und 5 sein");
	};
	
	
	public void addTeilnehmer(Teilnehmer teilnehmer)
	{if(teilnehmer != null)
	   {teilnehmerliste.add(teilnehmer);
	    teilnehmer.setTermin(this);
	   }
	else
		throw new IllegalArgumentException("teilnehmer darf nicht null sein!");
		
	}
	public void removeTeilnehmer(Teilnehmer teilnehmer)
	{if(teilnehmer != null)
	   {teilnehmerliste.remove(teilnehmer);
	    teilnehmer.removeTermin();
	   
	   }
	else
		throw new IllegalArgumentException("teilnehmer darf nicht null sein!");
		
	}
	
	public void addAnlage(Anlage anlage)
	{if(anlage != null)
	   {anlagen.add(anlage);
	    anlage.setTermin(this);
	   }
	else
		throw new IllegalArgumentException("anlage darf nicht null sein!");
	}
	
	public void removeAnlage(Anlage anlage)
	{if(anlage != null)
	{   anlagen.remove(anlage);
		anlage.removeTermin();
	}
	else
		throw new IllegalArgumentException("anlage darf nicht null sein!");
	
	}

  public String formatDate(Date date)
  {
   if(date == null ) throw new IllegalArgumentException("date darf nicht null sein!");
    return (sdf.format(date));
     
  }

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((adresse == null) ? 0 : adresse.hashCode());
		result = prime * result + ((anlagen == null) ? 0 : anlagen.hashCode());
		result = prime * result
				+ ((beschreibung == null) ? 0 : beschreibung.hashCode());
		result = prime * result
				+ ((prioritaet == null) ? 0 : prioritaet.hashCode());
		result = prime * result
				+ ((teilnehmerliste == null) ? 0 : teilnehmerliste.hashCode());
		result = prime * result
				+ ((terminAnfang == null) ? 0 : terminAnfang.hashCode());
		result = prime * result
				+ ((terminArt == null) ? 0 : terminArt.hashCode());
		result = prime * result
				+ ((terminEnde == null) ? 0 : terminEnde.hashCode());
		result = prime * result + ((thema == null) ? 0 : thema.hashCode());
		return result;
	}



	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Termin other = (Termin) obj;
		if (adresse == null) {
			if (other.adresse != null)
				return false;
		} else if (!adresse.equals(other.adresse))
			return false;
		if (anlagen == null) {
			if (other.anlagen != null)
				return false;
		} else if (!anlagen.equals(other.anlagen))
			return false;
		if (beschreibung == null) {
			if (other.beschreibung != null)
				return false;
		} else if (!beschreibung.equals(other.beschreibung))
			return false;
		if (prioritaet == null) {
			if (other.prioritaet != null)
				return false;
		} else if (!prioritaet.equals(other.prioritaet))
			return false;
		if (teilnehmerliste == null) {
			if (other.teilnehmerliste != null)
				return false;
		} else if (!teilnehmerliste.equals(other.teilnehmerliste))
			return false;
		if (terminAnfang == null) {
			if (other.terminAnfang != null)
				return false;
		} else if (!terminAnfang.equals(other.terminAnfang))
			return false;
		if (terminArt != other.terminArt)
			return false;
		if (terminEnde == null) {
			if (other.terminEnde != null)
				return false;
		} else if (!terminEnde.equals(other.terminEnde))
			return false;
		if (thema == null) {
			if (other.thema != null)
				return false;
		} else if (!thema.equals(other.thema))
			return false;
		return true;
	}
	
	public class IDcomparator implements Comparator<Termin>{

    @Override
    public int compare(Termin arg0, Termin arg1) {
      return arg0.getId().compareTo(arg1.getId());
    }
	}
	
	 public class PrioritaetsComparator implements Comparator<Termin>{

	    @Override
	    public int compare(Termin arg0, Termin arg1) {
	      return arg0.getPrioritaet().compareTo(arg1.getPrioritaet());
	    }
	  }
	
	
	

	
}
